package com.example.luke.shengdangxiaoattendance.Util;

import android.app.Activity;
import android.app.Notification;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.widget.Toast;

import com.example.f9demo.F9function;

import com.example.luke.shengdangxiaoattendance.MainActivity;
import com.jerome.serialport.SerialPortUtil;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * Created by luke on 12/31/16.
 */

public class ZYScanner {

    private Integer READ_SECTOR=6;
    private  F9function  sF9function ;
    private Activity activity;
    private String password="";
    private MIReaderUtils.MIReaderObj readerObj;
    private ArrayList<MIReaderUtils.MIReaderObj> miReaderObjArrayList;
    private int counter=READ_SECTOR;//读卡基数
    private ZYReaderTool zyReaderTool;
    private Handler taskHandler;
    private ZYWriteTool zyWriteTool;
    private int reduceAmount;//扣钱金额
    private int operate;// 0 ：读卡 , 1:写卡
    private int action=0;//0:发卡,1:充值,2:扣钱
    private  int reportType=7;//1:充值,2:取款,3:退款,7:随机消费/定额消费,6:商品消费
    private boolean fixPurchaseMode=false;
     public SerialPortUtil portUtil;
    private boolean readMode=true;
    private Timer readTimer;

    public  interface ZYListener{

        void getCardInfo(Double reduceAmount, Double remain, Double currentBalance);

        void getMICardNo(String cardNo, String ticketID) ;


         void showFixPurchaseCost(Double cost);

          void finishRead();


    }
    private ZYListener zyListener;

    public void setZyListener(ZYListener zyListener) {
        this.zyListener = zyListener;
    }


    public ZYScanner(Activity activity){

        this.activity=activity;
        init();

    }

    public void setREAD_SECTOR(Integer READ_SECTOR) {
        this.READ_SECTOR = READ_SECTOR;

        zyReaderTool.setREAD_SECTOR(READ_SECTOR);
        zyWriteTool.setREAD_SECTOR(READ_SECTOR);


    }


    public void setAction(int action) {
        this.action = action;
    }

    public ZYWriteTool getZyWriteTool() {
        return zyWriteTool;
    }

    public void setReduceAmount(int reduceAmount) {
        this.reduceAmount = reduceAmount;
    }

    public void setReportType(int reportType) {
        this.reportType = reportType;
    }

    private void init(){

        sF9function = new F9function(activity);
        password="123456789012";
        zyReaderTool=new ZYReaderTool(activity);
        zyReaderTool.setREAD_SECTOR(READ_SECTOR);

        zyWriteTool=new ZYWriteTool(activity);
        zyWriteTool.setREAD_SECTOR(READ_SECTOR);

        portUtil=SerialPortUtil.getInstance();
        portUtil.setOnDataReceiveListener(new SerialPortUtil.OnDataReceiveListener() {
            @Override
            public void onDataReceive(byte[] buffer, int size) {

            }
        });

        if (miReaderObjArrayList==null)
            miReaderObjArrayList=new ArrayList<>();


    }

    private void readCard(){

        String str_key = new String();

        String str_sec = new String();
        byte[] byte_key = new byte[6];
        byte[] byte_sec = new byte[1];
        byte[] byte_data = new byte[16];
        //Log.i("DEBUG++++>>","run the load key part!");
        if (password.length()!=12)
        {		Toast.makeText(activity, "密码有误", Toast.LENGTH_SHORT).show();
            return;
        }
        str_key = password;


        byte_key = ZYScannerTools.HexString2Bytes(str_key);

        str_sec = String.valueOf(counter);


        byte sec = Byte.parseByte( str_sec );

        Log.i("DEBUG++++>>","run the load key part!");

        long re = sF9function.rf_loadkey_hex(activity,(byte)0, sec, byte_key);

        if(re != 0)
        {
           // Toast.makeText(activity, "验证失败", Toast.LENGTH_SHORT).show();
          //   Toast.makeText(context, text, duration)
            return;
        }
        byte[] reData = new byte[4];
        reData = sF9function.rf_card(activity, (byte)0);
        if ((reData[0]==0)&(reData[1]==0)&reData[2]==0)
        {
            //Toast.makeText(activity, "无数据", Toast.LENGTH_SHORT).show();
            return;
        }

        long re1 = sF9function.rf_authentication(activity,(byte)0, sec);
        if(re1 != 0)
        {
//            if(1 == re1)
//               // Toast.makeText(activity, "��֤�������", Toast.LENGTH_SHORT).show();
//
//            else
//                Toast.makeText(activity, "��֤����У��ʹ���", Toast.LENGTH_SHORT).show();
            return;
        }

        byte_data = sF9function.rf_read_hex(activity,(byte)((sec * 4) + 0));
        String str_data = new String();
        str_data = "";
        for(int i = 0;i < 16;i++)
        {
            str_data += ZYScannerTools.byteToString(byte_data[i]);
        }
        readerObj=new MIReaderUtils.MIReaderObj();

        readerObj.setSector(counter);

        readerObj.getBlock().add(str_data);

        //   kuai0text.setText(str_data);//sector 0
        //String str_data = new String();
        byte_data = sF9function.rf_read_hex(activity,(byte)((sec * 4) + 1));
        //String str_data = new String();
        str_data = "";
        for(int i = 0;i < 16;i++)
        {
            str_data += ZYScannerTools.byteToString(byte_data[i]);
        }
        readerObj.getBlock().add(str_data);

       // kuai1text.setText(str_data);sector 1
        byte_data = sF9function.rf_read_hex(activity,(byte)((sec * 4) + 2));
        //String str_data = new String();
        str_data = "";
        for(int i = 0;i < 16;i++)
        {
            str_data += ZYScannerTools.byteToString(byte_data[i]);
        }

        readerObj.getBlock().add(str_data);

      //  kuai2text.setText(str_data);sector 2
     //   sF9function.rf_beep(activity,(byte)10);


        analyzeResult();

    }

//    public void printReceipt(String date, String ticketId, String cardId, String totalPrice, ArrayList<PurchaseReport> purchaseReports)
//    {//消费发票
//
//        try {
//
//            printText("日期 : " + date,false);
//
//            printText("票号 : "+ ticketId,false);
//
//            printText("==============================",false);
//
//            String titles="  项目     数量   单价   小计  ";
////
//           printText(titles,false);
//
//            String space="";
//            for (int i=0;i<titles.length();i++){
//                space=space+"   ";
//            }
//
//            for (PurchaseReport report:purchaseReports){
//
//                StringBuilder itemContent=new StringBuilder(space);
//
//                boolean seperateName=false;
//                int nameIndex=(titles.indexOf("项")-(report.getCommodityName().length())/2);
//                int amountIndex=titles.indexOf("数");
//                if (nameIndex<0)
//                    nameIndex=0;
//                int differIndex=0;
//
//                if (titles.indexOf("项")+report.getCommodityName().length()>amountIndex){
//                    seperateName=true;
//                    differIndex=titles.indexOf("项")+report.getCommodityName().length()-amountIndex+2;//留个"数"字前一个空格
//
//                    String temp=report.getCommodityName().substring(nameIndex,amountIndex-differIndex);
//
//                    itemContent.replace(nameIndex,amountIndex-differIndex,temp);
//
//                }else {
//                    itemContent.replace(nameIndex,report.getCommodityName().length(),report.getCommodityName());
//
//                }
//
//
//                String volume= String.valueOf(report.getVolume());
//
//                itemContent.replace(amountIndex,titles.indexOf("量"),volume);
//
//
//                int priceIndex=titles.indexOf("单");
//                itemContent.replace(priceIndex,titles.indexOf("价"),report.getSaleCost());
//
//                int totPriceIndex=titles.indexOf("小")+(report.getCost().length()/2);
//                itemContent.replace(totPriceIndex,titles.indexOf("计")+2,report.getCost());
//                String finResult=itemContent.toString();
//
//
//                finResult=finResult.replaceAll("\\s+$", "");//删除后面的空格
//                printText(finResult,false);
//
//                if (seperateName) {
//                    String temp = report.getCommodityName().substring(amountIndex - differIndex, report.getCommodityName().length());
//                   printText(temp,false);
//
//
//                }
//
//
//
//            }
//
//
//         printText("==============================",false);
//
//         printText("合计 : "+totalPrice,false);
//
//         printText("     \n\n\n\n",true);
//
//
//        }catch (Exception e){
//
//           GlobalFunction.printTextByTag(e.getMessage());
//
//        }
//
//
//    }

        public void printText(String text, boolean stat){//打印清单


         try {

             String hexStr=   MIReaderUtils.chineseToGBK(text);

           byte[] buff=   MIReaderUtils.hexStringToByte(hexStr);


             if (!stat)
            portUtil.sendBuffer(buff);
            else//留更多的换行
             portUtil.sendBufferWithGreaterSpace(buff);


        }catch (Exception e){

             GlobalFunction.printTextByTag(e.getMessage());
        }


      //  portUtil.sendCmds(content);


    }
    public void closePort(){

        portUtil.closeSerialPort();
    }
    MIReaderUtils.MIReaderObj getCorrespondSectorObj(int sector){
        MIReaderUtils.MIReaderObj miReaderObj=new MIReaderUtils.MIReaderObj();
        for (MIReaderUtils.MIReaderObj temp:this.miReaderObjArrayList){
            GlobalFunction.printTextByTag(temp.getSector()+""+" sector");

            if (temp.getSector().equals(sector)){
                miReaderObj=temp;

                break;

            }
        }
        return miReaderObj;

    }

    void writeCard(MIReaderUtils.MIReaderObj miReaderObj){
        String str_key = new String();

        String str_snr = new String();
        String str_kuai0 = new String();
        String str_kuai1 = new String();
        String str_kuai2 = new String();
        byte[] byte_key = new byte[6];
        byte[] byte_snr = new byte[1];
        byte[] byte_data0 = new byte[16];
        byte[] byte_data1 = new byte[16];
        byte[] byte_data2 = new byte[16];
        //Log.i("DEBUG++++>>","run the load key part!");
        if (password.length()!=12)
        {		Toast.makeText(activity, "������12λ����", Toast.LENGTH_LONG).show();
            return;
        }
        str_key = password;

        str_kuai0 = miReaderObj.getBlock().get(0).toString();
        str_kuai1 = miReaderObj.getBlock().get(1).toString();
        str_kuai2 = miReaderObj.getBlock().get(2).toString();

        GlobalFunction.printTextByTag(str_kuai0+":"+str_kuai1+":"+str_kuai2);
        if (str_kuai0.length()!=32)
        {	Toast.makeText(activity, "块1没有32位", Toast.LENGTH_LONG).show();
            return;
        }
        if (str_kuai1.length()!=32)
        {	Toast.makeText(activity, "块二没有32位", Toast.LENGTH_LONG).show();
            return;
        }
        if (str_kuai2.length()!=32)
        {	Toast.makeText(activity, "块三没有32位", Toast.LENGTH_LONG).show();
            return;
        }

        //	Log.i("DEBUG++++>> the key is",str_key);
        byte_key =ZYScannerTools.HexString2Bytes(str_key);
        str_snr = String.valueOf(miReaderObj.getSector());
        //Log.i("DEBUG++++>> the snr is",str_snr);
        //byte_snr= HexString2Bytes(str_snr);
        byte_snr[0] =(byte) Integer.valueOf(str_snr).intValue();
        //Log.i("DEBUG++++>>","run the load key part!");
        byte_data0 = ZYScannerTools.HexString2Bytes(str_kuai0);
        byte_data1 = ZYScannerTools.HexString2Bytes(str_kuai1);
        byte_data2 =ZYScannerTools. HexString2Bytes(str_kuai2);
        long re = sF9function.rf_loadkey_hex(activity,(byte)0, byte_snr[0], byte_key);

        if(re != 0)
        {
            Toast.makeText(activity, "�����������", Toast.LENGTH_LONG).show();
            // Toast.makeText(context, text, duration)
            return;
        }
        byte[] reData = new byte[4];
        reData = sF9function.rf_card(activity, (byte)0);
        if ((reData[0]==0)&(reData[1]==0)&reData[2]==0)
        {	Toast.makeText(activity, "�޿�", Toast.LENGTH_LONG).show();
            return;
        }
        long re1 = sF9function.rf_authentication(activity,(byte)0, byte_snr[0]);
        if(re1 != 0)
        {
//            if(1 == re1)
//                Toast.makeText(activity, "��֤�������", Toast.LENGTH_LONG).show();
//                // Toast.makeText(context, text, duration)
//            else
//                Toast.makeText(MainActivity1.this, "��֤����У��ʹ���", Toast.LENGTH_LONG).show();
//            return;
        }
        long re2 = sF9function.rf_write_hex(activity,(byte)((byte_snr[0] * 4) + 0),byte_data0);
//        if(re2 != 0)
//        {
//            Toast.makeText(MainActivity1.this, "д��0����", Toast.LENGTH_LONG).show();
//            return;
//        }
        long re3 = sF9function.rf_write_hex(activity,(byte)((byte_snr[0] * 4) + 1),byte_data1);
        if(re3 != 0)
        {
            Toast.makeText(activity, "д��1����", Toast.LENGTH_LONG).show();
            return;
        }
        long re4 = sF9function.rf_write_hex(activity,(byte)((byte_snr[0] * 4) + 2),byte_data2);
        if(re4 != 0)
        {
            Toast.makeText(activity, "д��2����", Toast.LENGTH_LONG).show();
            return;
        }
        //Toast.makeText(activity, "写卡成功", Toast.LENGTH_LONG).show();

        sF9function.rf_halt(activity);//���߿�



    }

    private int mInterval = 100;

    private Runnable readCardTask;

    private void prepareToRead(){//读卡前的初始化
        operate=0;
        counter=READ_SECTOR;
        miReaderObjArrayList.clear();
        readCardStatus=false;
        readMode=true;

    }

    public void startFixPurchaseMode(){//开启定额模式
        reportType=7;
        fixPurchaseMode=true;
        prepareToWrite();




    }

    private boolean handleFixPurchase(){
        boolean stat=true;

      //  reduceAmount= FixPriceTimeSchedule.getInstance().getCurrentFixPrice(zyReaderTool.getMICardType());


        if (reduceAmount>0){

            fixPurchaseMode=true;
            action=2;


            if (zyListener!=null)
                zyListener.showFixPurchaseCost(reduceAmount/100.);

            prepareToWrite();

        }else {

              GlobalFunction.ToastAlert(activity,"未到刷卡时间");

            stat=false;

            if (zyListener!=null)
                zyListener.finishRead();


        }

   return  stat;

    }

    private     void  startWrite(){//先读卡后写卡

        if (fixPurchaseMode)
            if (!handleFixPurchase())
                return;



        //  writeCard(miReaderObjArrayList.get(1));
        try {
            switch (action){
                case 0://发卡
                {
                    zyWriteTool.issueCard();
                    miReaderObjArrayList=zyWriteTool.getMiReaderObjArrayList();

                    for (MIReaderUtils.MIReaderObj readerObj : miReaderObjArrayList)
                        writeCard(readerObj);


                    if (zyListener!=null)
                        zyListener.finishRead();


                }

                    break;

                case 1://充值
                 {

                     topUpCard();

                 }
                  break;

                case 2:{

                    chargeCard();

                }
                break;

            }
            sF9function.rf_beep(activity,(byte)10);//开启喇叭

        }catch (Exception e){

            GlobalFunction.printTextByTag("write err");

        }


    }
    public void prepareToWrite(){


        try {

            startRead();
            operate=1;

        }catch (Exception e){

            GlobalFunction.printTextByTag("write err");

        }

    }

    public void startRead(){








      prepareToRead();
      readTimer  = new Timer();
        readTimer.schedule(new TimerTask()
        {
            @Override
            public void run()
            {

                    processCardContent();
                // TODO do your thing
            }
        }, 0, 1000);



//        ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
//        exec.scheduleAtFixedRate(new Runnable() {
//            @Override
//            public void run() {
//                // do stuff
//
//
//
//            }
//
//        }, 0, 1, TimeUnit.SECONDS);





    }
    private void processCardContent(){
        //先清空本地数据
    //    GlobalFunction.printTextByTag("start read");
        readCard();

        counter=counter+1;

        if (counter>READ_SECTOR+1)
            counter=READ_SECTOR;

    }

    private void showCardContent(){
        GlobalFunction.printTextByTag("process card");




        if (zyListener!=null){
            zyListener.getMICardNo(zyReaderTool.getMICardNo(),"");
//            zyListener.finishRead();

        }
        GlobalFunction.printTextByTag("process card finished");
       // zyReaderTool.showCardM1CardInfoContent();
        sF9function.rf_beep(activity,(byte)10);
    }

   private boolean readCardStatus=false;

    private void analyzeResult(){

        miReaderObjArrayList.add(readerObj);

        if (miReaderObjArrayList.size()>1){

            readCardStatus=true;

            zyWriteTool.setMiReaderObjArrayList(miReaderObjArrayList);
            zyReaderTool.setMiReaderObjArrayList(miReaderObjArrayList);
            GlobalFunction.printTextByTag("operate : " + operate);
           stopReadCard();
            startOperate();



        }
    }

    private void startOperate(){

        switch (operate){

            case 0://读卡

                showCardContent();

                break;

            case 1://写卡

               startWrite();

                break;
        }
    }


    int currentBalance;//操作之前的金额
    int totalAmount;//操作后的金额

    private void topUpCard(){

        int backUpIndex=getBackUpIndex();
        String value=MIReaderUtils.getStringAtRange(getMiCardValue(READ_SECTOR,backUpIndex),4,6);
        value=MIReaderUtils.convertHexPosition(value);
        currentBalance= Integer.valueOf(MIReaderUtils.convertToDecimal(value));


       totalAmount=currentBalance+reduceAmount;
         String finBalance= zyWriteTool.chargeBalance(totalAmount);

        MIReaderUtils.MIReaderObj miReaderObj= getCorrespondSectorObj(READ_SECTOR);
        miReaderObj.getBlock().set(backUpIndex,finBalance);
         miReaderObj.getBlock().set(backUpIndex,increaseCardIndex()); //加卡次数
         writeCard(miReaderObj);


    }

    private String increaseCardIndex(){//增加卡次数


        //    getBackUpIndex();
        int index=getBackUpIndex();
        String value= getMiCardValue(READ_SECTOR, index);
        Integer card_index= Integer.valueOf(MIReaderUtils.convertToDecimal1(value.substring(0, 4)));

        card_index=card_index+1;

        String temp=MIReaderUtils.checkContentLength(MIReaderUtils.convertToHexString(card_index),2);

        String finalVal=value.replace(value.substring(0, 4), temp);



       saveRecord(card_index);

        return finalVal;

    }


    private void chargeCard(){
        int backUpIndex=getBackUpIndex();

        String value=MIReaderUtils.getStringAtRange(getMiCardValue(READ_SECTOR,backUpIndex),4,6);
        value=MIReaderUtils.convertHexPosition(value);

        currentBalance= Integer.valueOf(MIReaderUtils.convertToDecimal(value));

        if (currentBalance<reduceAmount){//卡里的钱不够

            GlobalFunction.ToastAlert(activity,"非常抱歉，当前余额不足");
            stopReadCard();

        }else {


            totalAmount=currentBalance-reduceAmount;
            String finBalance= zyWriteTool.chargeBalance(totalAmount);
            MIReaderUtils.MIReaderObj miReaderObj= getCorrespondSectorObj(READ_SECTOR);
            miReaderObj.getBlock().set(backUpIndex,finBalance);
            miReaderObj.getBlock().set(backUpIndex,increaseCardIndex());

            writeCard(miReaderObj);

        }
    }

    private void saveRecord(int index){
//            GlobalFunction.printTextByTag("a");
//        String ticketID=GlobalFunction.getUniqueId();
//
//        try {
//
//            GlobalFunction.printTextByTag("insert card record");
////
//            CardRecord cardRecord= new CardRecord(ticketID);
//            cardRecord.setUsageCount(index);
//            cardRecord.setReportType(reportType);
//            cardRecord.setOperator(Operator.getIntance().getEmployeeID());
//            cardRecord.setCardName(zyReaderTool.getMIcardUserName());
//            cardRecord.setPurchaseAmount(reduceAmount/100.);
//            cardRecord.setRemain(totalAmount/100.);
//
//            DingHanDB.getInstance(activity).insert(CardRecord.DH_TABLE_NAME,cardRecord);
//
//            //回调
//            if (zyListener!=null){
//
//                 zyListener.getCardInfo(reduceAmount/100.,currentBalance/100.,totalAmount/100.);
//                zyListener.getMICardNo( zyReaderTool.getMICardNo(),ticketID);
//
//
//            }
//
//
//        }catch (Exception e){
//    GlobalFunction.printTextByTag(e.getMessage());
//
//
//        }
    }




  public void stopReadCard(){

        taskHandler=null;
        readCardTask=null;
        fixPurchaseMode=false;
        readMode=false;
readTimer.cancel();

    }



    Integer getBackUpIndex(){
        Integer index=0;
        String value= getMiCardValue(READ_SECTOR,0).substring(0,4);
        String value2=getMiCardValue(READ_SECTOR,1).substring(0,4);

        Integer integer= Integer.valueOf(MIReaderUtils.convertToDecimal(value));
        Integer integer2= Integer.valueOf(MIReaderUtils.convertToDecimal(value2));
        if (integer>integer2){
            index=0;

        }else if(integer2>integer){
            index=1;

        }else {

            value= getMiCardValue(READ_SECTOR, 1).substring(8, 14);

            String temp=MIReaderUtils.convertToDecimal(value);
            Integer integer3= Integer.valueOf(temp);

            String value3=MIReaderUtils.convertToDecimal(getMiCardValue(READ_SECTOR, 0).substring(8, 14)) ;
            Integer integer1= Integer.valueOf(value3);

            if (integer1<integer3){
                index=0;

            }else {
                index=1;
            }
        }

        return index;

    }

    String getMiCardValue(Integer sector, Integer block) {


        MIReaderUtils.MIReaderObj miReaderObj= getCorrespondSectorObj(sector);


        String value = miReaderObj.getBlock().get(block);

        return value;

    }


    public static String getWeekday(){

        String temp="";
        int dayOfWeek=Calendar.getInstance().get(Calendar.DAY_OF_WEEK);

        if (dayOfWeek==Calendar.MONDAY){

            temp="星期一";

        }
        else if (dayOfWeek==Calendar.TUESDAY){

            temp="星期二";

        }

        else if (dayOfWeek==Calendar.WEDNESDAY){

            temp="星期三";

        }
        else if (dayOfWeek==Calendar.THURSDAY){

            temp="星期四";

        }
        else if (dayOfWeek==Calendar.FRIDAY){

            temp="星期五";

        }
        else if(dayOfWeek==Calendar.SATURDAY) {

            temp="星期六";

        }else if(dayOfWeek==Calendar.SUNDAY){

            temp="星期日";

        }
        return temp;



    }

}
